// C++尾置返回类型语法详解
// 1. 基本语法
// 尾置返回类型（Trailing Return Type）是C++11引入的一种函数声明语法，允许将返回类型放在函数参数列表之后。

// 传统语法
返回类型 函数名(参数列表);

// 尾置返回类型语法
auto 函数名(参数列表) -> 返回类型;

// 2. 语法组成部分
//  1)auto关键字：
//      在函数声明开头使用auto
//      这里的auto不是用于类型推导，只是语法的一部分
//      它告诉编译器"真正的返回类型将在箭头后指定"
//  2)箭头符号 ->：
//      分隔函数参数列表和返回类型
//      指示尾置返回类型的开始
//  3)返回类型表达式：
//      箭头后面是完整的返回类型表达式
//      可以是简单类型，也可以是复杂的依赖类型表达式

// 3. 基本示例
// 传统语法
int add(int a, int b);

// 尾置返回类型语法
auto add(int a, int b) -> int;

// 4. 主要用途
// 4.1 使用函数参数确定返回类型
// 无法编译：在参数声明前无法使用参数
// template<typename T, typename U>
// decltype(t + u) add(T t, U u);

// 正确：可以在返回类型中使用参数
template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u)
{
    return t + u;
}

// 4.3 SFINAE技术（替换失败不是错误）
// 仅当T有size()方法时启用
// decltype(编译条件1,编译条件2...,编译条件k，表达式决定返回类型)
template <typename T>
auto getSize(const T &container) -> decltype(container.size(), unsigned int())
{
    return container.size();
}

// 后备版本
template <typename T>
auto getSize(...) -> unsigned int
{
    return 0;
}

// 4.4 与std::enable_if结合
// 仅对整数类型启用
template <typename T>
auto process(T value) ->
    typename std::enable_if<std::is_integral<T>::value, void>::type
{
    std::cout << "整数处理: " << value << std::endl;
}

// 5. C++14的改进
// C++14允许直接使用auto作为返回类型，编译器会自动推导：
// C++11需要尾置返回类型
template <typename T, typename U>
auto add11(T t, U u) -> decltype(t + u)
{
    return t + u;
}

// C++14可以直接使用auto
template <typename T, typename U>
auto add14(T t, U u)
{
    return t + u; // 返回类型自动推导为t+u的类型
}

// 6. 注意事项
// typename关键字：
// 当返回类型依赖于模板参数时，可能需要typename关键字！！！！！！！！！！！！！！！！！

// 与lambda表达式的关系：
// Lambda表达式也使用类似的尾置返回类型语法
auto lambda = [](int x) -> double
{ return x * 1.5; };